package com.qdlc.p2p.dal.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;

import com.qdlc.p2p.common.constant.BorrowStyle;
import com.qdlc.p2p.common.exception.BorrowException;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.FinanFlowExecption;
import com.qdlc.p2p.common.exception.UserPayPwdException;
import com.qdlc.p2p.common.util.BeanUtil;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.common.util.Page;
import com.qdlc.p2p.common.util.PropertiesUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.common.util.code.MD5;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dao.AdditionalFlowInvestorDao;
import com.qdlc.p2p.dal.dao.UserCacheDao;
import com.qdlc.p2p.dal.dao.UserIdentifyDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.AdditionalFlowInvestor;
import com.qdlc.p2p.dal.dto.AdditionalFlowProject;
import com.qdlc.p2p.dal.dto.AdditionalFlowRepayPlan;
import com.qdlc.p2p.dal.dto.AdditionalFlowYieldPlan;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserCache;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.model.interest.EachPlan;
import com.qdlc.p2p.dal.model.interest.InstallmentRepaymentCalculator;
import com.qdlc.p2p.dal.model.interest.InterestCalculator;
import com.qdlc.p2p.dal.model.interest.MonthlyInterestCalculator;
import com.qdlc.p2p.dal.model.interest.OnetimeRepaymentCalculator;

/**
 * 理财项目model
 * @author wjx
 * @version 2.0
 * @date 2015年5月15日 下午1:46:20
 */
public class FlowProjectModel extends AdditionalFlowProject {
	
	
	/**
	 * 添加
	 */
	public static final byte PROJECT_ADD_STATUS = 0;
	
	/**
	 * 初审通过
	 */
	public static final byte PROJECT_VERIFY_SUCCESS_STATUS = 1;
	
	/**
	 * 初审不通过
	 */
	public static final byte PROJECT_VERIFY_FAIL_STATUS = 2;
	
	/**
	 * 满标，停止申购
	 */
	public static final byte PROJECT_TENDER_OVER_STATUS = 3;
	
	/**
	 *项目结束
	 */
	public static final byte PROJECT_END_STATUS = 6;
	
	/**
	 * 交易密码
	 */
	private String payPwd;
	
	private String resultFlag;
	
	/** 当前页码 */
	private int page = 1;

	/** 每页数据条数 */
	private int rows = Page.ROWS;
	
	private String userName;
	
	private String email;
	
	private long userId;
	/**
	 * 查询状态
	 */
	private byte queryStatus=99;
	
	/**
	 * 投标订单号
	 */
	private String subOrdId;
	
	/**
	 * 投标时间
	 */
	private String subOrdDate;
	
	/**
	 * 搜索名称
	 */
	private String  searchName;
	
	/**
	 * 利率搜索
	 */
	private int aprSearch;
	
	/**
	 * 金额搜索
	 */
	private int moneySearch;
	
	/**
	 * 名称搜索
	 */
	private String borrowName;
	
	/**
	 *期限搜索
	 */
	private int timeSearch;
	
	/** 我要投资 - 排序 **/
	private int order;
	
	/**
	 * 是否有还款记录
	 * 1：有，0：无
	 */
	private int isRepayTag =0;
	
	/**
	 * 将基类封装到model中，创建model对象
	 * @param flowProject
	 * @return
	 */
	public static FlowProjectModel instance(AdditionalFlowProject flowProject) {
		FlowProjectModel flowProjectModel = new FlowProjectModel();
		BeanUtils.copyProperties(flowProject, flowProjectModel);
		return flowProjectModel;
	}
	
	/**
	 * 将当前model的属性封装到实体bean中
	 * @return
	 */
	public AdditionalFlowProject prototype(){
		AdditionalFlowProject flowProject = new AdditionalFlowProject();
		BeanUtils.copyProperties(this, flowProject);
		return flowProject;
	}
	
	/**
	 * 发布理财项目时进行校验
	 */
	public void checkAddFlowProject(){
		
		//校验是否选择了用户
		if (StringUtil.isBlank(getEmail())) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001007"),BusinessException.TYPE_JSON);
		}
		
		
		//校验项目金额
		if (getAccount()<=500) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001005"),BusinessException.TYPE_JSON);
		}
		//校验每份金额是否为整数
		int newEachMoney = (int)getEachMoney();
		if (newEachMoney !=getEachMoney()) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001006"),BusinessException.TYPE_JSON);
		}
		//校验项目份数是否为整数份
		double checkCopies =getAccount()%getEachMoney();
		if (checkCopies>0) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001001"),BusinessException.TYPE_JSON);
		}
		//校验是否输入了期限
		if (getTimeLimit()<1) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001002"),BusinessException.TYPE_JSON);
		}
		//校验项目最低购买份数
		int countCopies =(int) (getAccount()/getEachMoney());
		if (getStartCopies()>countCopies) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001003"),BusinessException.TYPE_JSON);
		}
		this.setTotalCopies(countCopies);
		//校验利率
		if (getApr() <=0) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103001004"),BusinessException.TYPE_JSON);
		}
		
	}
	
	/**
	 * App 投资参数校验
	 * @return
	 */
	public Map<String,Object> validParams(){
		
		if(StringUtil.isBlank(getId()) || getId() < 1){
			Map<String,Object> data = new HashMap<String,Object>();
			data.put("resCode", "0");
			data.put("resMsg", PropertiesUtil.getValue("AppAdditionalFlow01"));
			return data;
		}
		
		if(StringUtil.isBlank(getPage()) || getPage() < 1){
			Map<String,Object> data = new HashMap<String,Object>();
			data.put("resCode", "0");
			data.put("resMsg", PropertiesUtil.getValue("AppAdditionalFlow02"));
			return data;
		}
		return null;
	}
	
	/**
	 * 校验购买人信息
	 * @param flowInvestor
	 */
	public void  checkTender(AdditionalFlowInvestor flowInvestor){
		UserIdentifyDao userIdentifyDao = (UserIdentifyDao) BeanUtil.getBean("userIdentifyDao");
		AccountDao accountDao = (AccountDao) BeanUtil.getBean("accountDao");
		User user = flowInvestor.getUser();
		UserIdentify userIdentify = userIdentifyDao.findObjByProperty("user.userId", user.getUserId());
		//校验用户信息
		validInvestor(userIdentify);
		UserCacheDao userCacheDao = (UserCacheDao) BeanUtil.getBean("userCacheDao");
		UserCache userCache = userCacheDao.findObjByProperty("user.userId", user.getUserId());
		if (userCache.getStatus() == 1) {
			throw new BorrowException(MessageUtil.getMessage("MF103002004"));
		}
		Account account = accountDao.findByUserId(user.getUserId());
		if (account.getUseMoney()<flowInvestor.getBuyMoney()) { //校验可用余额
			throw new BorrowException(MessageUtil.getMessage("MF103002005"));
		}
	
		//校验理财产品信息
		if (getStatus() !=PROJECT_VERIFY_SUCCESS_STATUS) {
			throw new BorrowException(MessageUtil.getMessage("MF103002008"));
		}
	}
	
	public void checkTenderPwd(User user){
		//校验交易密码
		/*	if (UserModel.instance(user).getIsPayLock() == 1) {
				throw new BorrowException("MF103002009", 1);
			}*/
			if (StringUtil.isBlank(getPayPwd())) {
				throw new BorrowException(MessageUtil.getMessage("MF103002006"));
			}
			String pwd = MD5.encode(getPayPwd());
			if (!pwd.equals(user.getPayPwd())) {
				throw new UserPayPwdException(MessageUtil.getMessage("MF103002007"));
			}/* else {
				// 如果正确则清除交易密码错误信息
				UserModel.instance(user).cleanPayFail();
			}*/
	}
	
	
	/**
	 * 校验用户认证信息
	 * @param userIdentify
	 */
	private void validInvestor(UserIdentify userIdentify){
		
		//校验用户真实姓名
		if (userIdentify.getRealNameStatus() !=1) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103002002"));
		}
		
		//手机认证
		if (userIdentify.getMobilePhoneStatus()!=1) {
			throw new FinanFlowExecption(MessageUtil.getMessage("MF103002003"));
		}
		
	}
	
	
	/**
	 * 购买成功，处理投资信息
	 * @param investor
	 * @param ic
	 * @return
	 */
	public AdditionalFlowInvestor buySuccess(AdditionalFlowInvestor investor ,InterestCalculator ic){
		AdditionalFlowInvestorDao additionalFlowInvestorDao = (AdditionalFlowInvestorDao)BeanUtil.getBean("additionalFlowInvestorDao");
		investor.setStatus(FlowInvestorModel.SUCCESS_STATUS); //设置成功状态
		//计算预期收益
		double totalMoney = ic.repayTotal(); //收益总额
		//除本金以外的收益
		double profit = BigDecimalUtil.sub(totalMoney, investor.getBuyMoney());
		investor.setWaitYields(profit);
		additionalFlowInvestorDao.save(investor);
		return investor;
	}
	
	/**
	 * 创建理财人的预期收益计划
	 * @param investor
	 * @param ic
	 * @return
	 */
	public List<AdditionalFlowYieldPlan> createYieldPlanList(AdditionalFlowInvestor investor ,InterestCalculator ic){
		List<AdditionalFlowYieldPlan> yieldPlanList = new ArrayList<AdditionalFlowYieldPlan>();
		List<EachPlan> eachPlanList = ic.getEachPlanList();
		AdditionalFlowProject project = investor.getFlowProject();
		double totalProfit = 0;  //收益总额
		double totalMoney = 0;// 本金总额
		int i = 0;//期数
		for (EachPlan each : eachPlanList) {
			AdditionalFlowYieldPlan yieldPlan = fiddYieldPlan(each, investor);
			if (i==eachPlanList.size()-1) { //判断是否为最后一期
				//计算利息差值
				double pro = investor.getWaitYields();
				double diffpro = BigDecimalUtil.sub(pro, totalProfit);
				yieldPlan.setWaitYields(diffpro);
				//计算本金收益差值
				double money = investor.getBuyMoney();
				double diffMoney = BigDecimalUtil.sub(money, totalMoney);
				yieldPlan.setWaitMoney(diffMoney);
			}
			totalMoney = BigDecimalUtil.add(yieldPlan.getWaitMoney(),totalMoney); //本金相加
			totalProfit = BigDecimalUtil.add(yieldPlan.getWaitYields(),totalProfit);// 利息相加
			yieldPlan.setPeriod(i++);
			//设置时间，T+1计息方式
			Date date = DateUtil.rollDay(DateUtil.getNow(), 1);
			//设置时间,判断是按天还是按月计息
			if (project.getIsDay() ==1) {
				//将时间转换为当天最终时间
				Date newDate = DateUtil.rollDay(date, project.getTimeLimit());//
				yieldPlan.setWaitTime(DateUtil.getDayEndTime(newDate.getTime()/1000));
			}else{
				Date newDate = DateUtil.rollMon(date, i);
				yieldPlan.setWaitTime(DateUtil.getDayEndTime(newDate.getTime()/1000));
			}
			yieldPlan.setFlowProject(project);
			yieldPlan.setFlowInvestor(investor);
			yieldPlan.setUser(investor.getUser());
			yieldPlanList.add(yieldPlan);
		}
		return yieldPlanList;
	}
	
	/**
	 * 封装理财待收记录
	 * @param each
	 * @param investor
	 * @return
	 */
	public AdditionalFlowYieldPlan fiddYieldPlan(EachPlan each,AdditionalFlowInvestor investor){
		AdditionalFlowYieldPlan yieldPlan = new AdditionalFlowYieldPlan();
		yieldPlan.setFlowInvestor(investor);
		yieldPlan.setWaitMoney(each.getCapital());
		yieldPlan.setWaitYields(each.getInterest());
		yieldPlan.setStatus(FlowInvestorModel.YIELD_PLAN_INIT_STATUS);
		return yieldPlan;
	}
	
	
	/**
	 * 创建借款人的待还计划
	 * @param yieldPlanList
	 * @return
	 */
	public List<AdditionalFlowRepayPlan> createRepayList(List<AdditionalFlowYieldPlan> yieldPlanList){
		List<AdditionalFlowRepayPlan> repayPlanList = new ArrayList<AdditionalFlowRepayPlan>();
		for (AdditionalFlowYieldPlan yieldPlan : yieldPlanList) {
			AdditionalFlowRepayPlan repayPlan = new AdditionalFlowRepayPlan();
			repayPlan.setPeriod(yieldPlan.getPeriod());
			repayPlan.setFlowProject(yieldPlan.getFlowProject());
			repayPlan.setUser(yieldPlan.getFlowProject().getUser());
			repayPlan.setRepayCopies(yieldPlan.getWaitYields());
			repayPlan.setRepayMoney(yieldPlan.getWaitMoney());
			repayPlan.setYieldPlanId(yieldPlan.getId());
			repayPlan.setRepayTime(yieldPlan.getWaitTime());
			repayPlan.setStatus(RepayPlanModel.INIT_STATUS);
			repayPlanList.add(repayPlan);
		}
		
		
		return repayPlanList;
		
	}
	
	
	
	/**
	 * 生成计算器
	 * @param money
	 * @return
	 */
	public InterestCalculator interestCalculator(double money){
		InterestCalculator ic = null;
		Date date = DateUtil.getNow();
		if (getIsDay() == 1 && getRepayStyle() == BorrowStyle.STYLE_ONETIME_REPAYMENT) { // 天标,一次性还款
			ic = new OnetimeRepaymentCalculator(money, getApr()/100, date, 1, 0);
		} else if (getRepayStyle() == BorrowStyle.STYLE_ONETIME_REPAYMENT) { // 一次性还款
			ic = new OnetimeRepaymentCalculator(money, getApr()/100, date, getTimeLimit(), 0);
		} else if (getRepayStyle() == BorrowStyle.STYLE_MONTHLY_INTEREST) { // 每月还息到期还本
			ic = new MonthlyInterestCalculator(money, getApr()/100, date, getTimeLimit(), true, 0);
		} else if (getRepayStyle() == BorrowStyle.STYLE_INSTALLMENT_REPAYMENT) { // 等额本息
			ic = new InstallmentRepaymentCalculator(money, getApr()/100, date, getTimeLimit(), 0);
		}
		if (getIsDay() == 1) {
			ic.calculator(getIsDay());
		} else {
			ic.calculator();
		}
		return ic;
	}

	
	/**
	 *计算总份数
	 */
	public void doTotalCopies(){
		double totalCop = getAccount()/getEachMoney();
		setTotalCopies((int)totalCop);
	}

	public String getPayPwd() {
		return payPwd;
	}

	public void setPayPwd(String payPwd) {
		this.payPwd = payPwd;
	}

	public String getResultFlag() {
		return resultFlag;
	}

	public void setResultFlag(String resultFlag) {
		this.resultFlag = resultFlag;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public byte getQueryStatus() {
		return queryStatus;
	}

	public void setQueryStatus(byte queryStatus) {
		this.queryStatus = queryStatus;
	}

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public String getSubOrdId() {
		return subOrdId;
	}

	public void setSubOrdId(String subOrdId) {
		this.subOrdId = subOrdId;
	}

	public String getSubOrdDate() {
		return subOrdDate;
	}

	public void setSubOrdDate(String subOrdDate) {
		this.subOrdDate = subOrdDate;
	}

	public String getSearchName() {
		return searchName;
	}

	public void setSearchName(String searchName) {
		this.searchName = searchName;
	}



	public int getOrder() {
		return order;
	}

	public void setOrder(int order) {
		this.order = order;
	}

	public int getAprSearch() {
		return aprSearch;
	}

	public void setAprSearch(int aprSearch) {
		this.aprSearch = aprSearch;
	}

	public int getMoneySearch() {
		return moneySearch;
	}

	public void setMoneySearch(int moneySearch) {
		this.moneySearch = moneySearch;
	}

	public String getBorrowName() {
		return borrowName;
	}

	public void setBorrowName(String borrowName) {
		this.borrowName = borrowName;
	}

	public int getTimeSearch() {
		return timeSearch;
	}

	public void setTimeSearch(int timeSearch) {
		this.timeSearch = timeSearch;
	}

	public int getIsRepayTag() {
		return isRepayTag;
	}

	public void setIsRepayTag(int isRepayTag) {
		this.isRepayTag = isRepayTag;
	}

	

	
	

	
	


}
